On-demand loading of dynamic scripting language code for reduced memory usage

ABSTRACT

A computer-implemented method and system for reducing the amount of memory space required to store applications written in dynamic scripting languages loads a program module into memory and removes a category of program code, such as debug information or function definitions, from the program module. The method and system also receives a request for debug information, or a function call or query, and determines whether or not the corresponding program code is in memory. If not, then the location in storage is identified where the program module is stored, and another copy containing the corresponding program code is loaded into memory. The corresponding program code is located and copied into the program module in memory, and a response is provided to the request.

PRIORITY CLAIM

The application claims priority to U.S. patent application Ser. No.14/629,197, filed Feb. 23, 2015, entitled “On-Demand Loading of DynamicScripting Language Code for Reduced Memory Usage,” which is incorporatedherein by reference in its entirety.

TECHNICAL FIELD

This description relates generally to compiling and loading dynamicscripting language code, and more particularly to reducing memory usagethrough on-demand compiling and loading of application source code indynamic scripting languages.

BACKGROUND

Dynamic scripting languages are widely used in many industry andacademic areas. For example, JavaScript is widely considered thedominant computer programming language for building client-side webapplications; PHP typically is the backbone used to build server-sideweb applications; Python is widely used in building both high-level andlow-level applications; Lua has been widely applied in the gamingindustry and in embedded systems; R and Matlab have become popular forparticular uses.

In general, the performance of dynamic scripting languages poses aconcern. For example, applications written in dynamic scriptinglanguages typically run slower and use more memory than applicationsbased on static languages. Yet, in many scenarios memory usage is ofcritical importance. In typical embedded systems, for example, if anapplication requires more memory than is available the application willcrash.

The memory used by an application generally includes a code section anda data section. In many applications, the code section can use up tohalf of the total required memory. As a result, reducing the amount ofmemory required for the code section can be an effective way to reduceoverall application memory usage.

Existing solutions to reduce the amount of memory required for the codesection include rewriting or restructuring the application to removeunnecessary code. This is made possible because applications typicallyinclude source code for all possible features of the application, eventhough some of the features generally will not be executed. Rewriting orrestructuring the code can ensure only necessary code is included in theapplication.

However, rewriting or restructuring the code is relatively laborintensive, and thus, relatively expensive. Moreover, the decisionregarding the usefulness or necessity of a section of code can beambiguous based purely on static information. A more certaindetermination often is only possible using the information available atruntime.

Another reason dynamic scripting languages use more memory space is thatby default dynamic scripting languages typically store all of therelevant debugging information for an application in the compiled objectcode, or bytecode, in memory. In some cases, the debug informationoccupies more than a third of the memory space used by the programmingcode. Nevertheless, the debug information typically is used only rarely,for example, when an error occurs during application execution or whenreflection functions are invoked during execution.

Existing solutions to reduce the amount of memory required for the codesection also include removing debug information by precompiling theapplication source code into bytecode. For example, Lua source code canbe precompiled using the “-s” command extension to strip all debugginginformation in the source code, although an equivalent approach is notavailable in some dynamic scripting languages. However, use of such anapproach does not permit retrieval of the debug information at runtime.In addition, when a runtime error occurs, the application is not able toreport useful information, such as the line number in the code where theerror occurred, variable names associated with the error, and the like.

In some cases, stripping the debug information from the code is not anacceptable solution, because certain application features required atruntime are dependent on the availability of the debugging information.Furthermore, removing the debugging information increases the deploymentcomplexity, because the additional precompile step with the “-s” optionis required to reach an intermediate stage (that is, bytecode) beforethe application is loaded into memory, whereas in general the dynamicscripting language source script has been directly executed.

Additionally, dynamic scripting language codes often are compressedusing common data compression algorithms. Even though the uncompressedversion of precompiled bytecode may occupy less memory than theuncompressed source code, after compression the precompiled code canoccupy more memory space than the original text-format source code.Thus, in some applications—for example, in embedded systems with limitedflash memory—it is desirable to store source code, rather thanprecompiled bytecode, to further reduce the amount of required memory.

SUMMARY

According to one embodiment of the present invention, a system forreducing a memory space required to store an application written in adynamic scripting language includes an input/output device that receivesa request corresponding to a segment of program code in a program modulein the dynamic scripting language. The system further includes anon-demand loader that determines whether or not the segment of programcode is in memory and identifies, in response to having determined thesegment of program code is not in memory, a location in storage where atleast a portion of the program module containing the segment of programcode is stored, locates the segment of program code in a second copy ofthe portion of the program module, and copies the segment of programcode into a first copy of the program module in memory. The system alsoincludes a code loader that loads the second copy of the portion of theprogram module containing the segment of program code from the storageinto memory.

According to another embodiment of the present invention, a method ofreducing the memory space required to store an application written in adynamic scripting language includes receiving a request corresponding toa segment of program code in the program module, determining whether ornot program code is in memory, and if not, identifying a location instorage where at least a portion of the program module containing thesegment of program code is stored. The method also includes loading asecond copy of the program module containing the segment of program codefrom storage into memory, locating the segment of program code in thesecond copy of the portion of the program module. The method furtherincludes copying the segment of program code into the first copy of theprogram module in memory.

The details of one or more embodiments of the invention are set forth inthe accompanying drawings and the description below. Other features,objects, and advantages of the invention will be apparent from thedescription and drawings, and from the claims.

DESCRIPTION OF THE DRAWINGS

FIG. 1 is a schematic view illustrating a dynamic-scripting-languagevirtual machine that employs an on-demand source-code loader inaccordance with an embodiment of the present invention.

FIG. 2 is a schematic view depicting a computing system that canimplement the dynamic-scripting-language virtual machine of FIG. 1.

FIG. 3 is a flowchart representing a method of on-demanddynamic-scripting language source-code debug information loading inaccordance with an embodiment of the present invention.

FIG. 4 is an illustration of a redacted function placeholder and acompiled dynamic scripting-language application tree structure inaccordance with an embodiment of the present invention.

FIG. 5 is a flowchart representing a method of on-demanddynamic-scripting language source-code function loading in accordancewith an embodiment of the present invention.

DETAILED DESCRIPTION

An embodiment of the present invention is shown in FIG. 1, whichillustrates an exemplary dynamic-scripting-language virtual machine 10that employs an on-demand dynamic scripting-language source-code loadingprocess in order to reduce the memory space required to store anapplication in dynamic-scripting-language source code 12. The virtualmachine 10 includes a code loader 14, an on-demand loader 16, aninterpreter 18, an object 20 and a client 22.

The code loader 14 reads the original-text source code 12, redacts eachapplication object 20 by removing a category of program code, and loads,or inserts, a redacted source code placeholder for each object 20 intomemory. For example, in one embodiment the code loader 14 removes debuginformation from each of the function objects in the source code 12during online compiling, and loads the redacted source code for eachobject 20 into memory. In another embodiment, the code loader 14generates a function stub for each function in the original source code12. For example, the function stub records meta information, such as thesource code filename, the function proto, and the start and end location(line and column numbers) of the function in the source file.

Thus, the virtual machine 10 removes a category of program code, such asdebug information or function code, and stores the location where tofind the original source code, when the virtual machine 10 loads andcompiles the source code into bytecode in memory. In an alternativeembodiment, the redacted function code section data is stored insecondary storage, such as a hard disk drive. Because the source codeplaceholders occupy relatively less memory space compared to the fullsource code, the memory consumption of the dynamic-scripting languageapplication is reduced.

When the object 20 subsequently is called or queried, or debuginformation is requested, the on-demand loader 16 prompts the codeloader 14 to reload the source code 12 and create a compiled treestructure of the function objects including the full function sectioncode or debug information. The on-demand loader 16 searches the treestructure for the function object that corresponds to the called orqueried object or the requested information. The code section or debuginformation is copied from the tree structure to the object 20, which isreturned to the requesting or calling client 22.

In various embodiments of the invention, the virtual machine 10 runtimeenvironment generates the requested debug information or code section ondemand and dynamically modifies the function stub to form a completefunction object according to the runtime behaviors. Thus, only functionsactually executed at run time are filled with code section or debuginformation in memory. All other functions in the source code arerepresented in memory by a redacted placeholder, for example, a functionstub or a function object without debug information.

The on-demand dynamic-scripting-language source-code loading systemsdescribed herein can offer advantages such as reduced memoryconsumption. The amount of memory required to store the bytecode isessentially reduced by the quantity of debug information or coderemoved, yet the detailed code sections or debug information is madeavailable when requested. There are no language specific limitations, sothis approach can be used with any dynamic scripting language. All ofthe components of the source code application can maintain the originalfeatures. In this transparent, purely dynamic approach, no additionalprecompilation step is required. The original source code can bemaintained in storage using any known compression algorithm.

As illustrated in FIG. 2, an exemplary computing device 30 that canimplement the dynamic-scripting-language virtual machine 10 of FIG. 1includes a processor 32, a memory 34, an input/output device (I/O) 36storage 38 and a network interface 40. The various components of thecomputing device 30 are coupled by a local data link 42, which invarious embodiments incorporates, for example, an address bus, a databus, a serial bus, a parallel bus, or any combination of these.

The computing device 30 communicates information to and requests inputfrom the user or other devices by way of the I/O 36, which in variousembodiments incorporates, for example, an interactive, menu-driven,visual display-based user interface, or graphical user interface (GUI),a pointing device, such as a, with which the user may interactivelyinput information using direct manipulation of the GUI. In someembodiments, direct manipulation includes the use of an alphanumericinput device, such as a keyboard, a pointing device, such as a mouse, atouchpad, a trackball, a joystick or a stylus, to select from a varietyof windows, icons and selectable fields, including selectable menus,drop-down menus, tabs, buttons, bullets, checkboxes, text boxes, and thelike. Nevertheless, various embodiments of the invention may incorporateany number of additional functional user interface schemes in place ofthis interface scheme, with or without the use of an alphanumeric inputdevice, a pointing device, buttons or keys, for example, using directvoice input.

The computing device 30 can be coupled to a communication network by wayof the network interface 40, which in various embodiments incorporates,for example, any combination of devices, as well as any associatedsoftware or firmware, configured to couple processor-based systems,including modems, access points, network interface cards, LAN or WANinterfaces, wireless or optical interfaces and the like, along with anyassociated transmission protocols, as may be desired or required by thedesign.

For example, the source code 12 can, in some embodiments, be containedin a remote storage communicatively interconnected to the computingsystem 30 by way of a communication network. In various embodiments, thecommunication network can include any viable combination of devices andsystems capable of linking computer-based systems, such as the Internet;an intranet or extranet; a local area network (LAN); a wide area network(WAN); a direct cable connection; a private network; a public network;an Ethernet-based system; a token ring; a value-added network; atelephony-based system, including, for example, T1 or E1 devices; anAsynchronous Transfer Mode (ATM) network; a wired system; a wirelesssystem; an optical system; a combination of any number of distributedprocessing networks or systems or the like.

The computing device 30 can be used, for example, to implement thefunctions of the components of the dynamic-scripting-language virtualmachine of FIG. 1. In various embodiments, the computing device 30 caninclude, for example, a server, a controller, a router, a workstation, amainframe computer, personal computer (PC), a note pad, a computingtablet, a personal digital assistant (PDA), a smart phone, or the like.Programming code, such as source code, object code or executable code,stored on a computer-readable medium, such as the storage 38 or aperipheral storage component coupled to the computing device 30, can beloaded into the memory 34 and executed by the processor 32 in order toperform the functions of the dynamic scripting-language virtual machine10.

Referring now to FIG. 3, an exemplary process flow is illustrated thatmay be performed, for example, by the dynamic-scripting-language virtualmachine 10 of FIG. 1 to implement an embodiment of the method describedin this disclosure for on-demand dynamic scripting-language source-codeloading. Blocks shown with dashed lines in FIG. 3 are optional itemsthat may not be performed in all implementations. The process begins atblock 50, where an object, such as a function, in the source code of anapplication written in a dynamic-scripting language is parsed. Forexample, in an embodiment, the object is parsed at run time by a codeloader module of a dynamic-scripting-language virtual machine.

The object is redacted, in block 52, to remove all debugging informationfrom the code. For example, in an embodiment, the debug information isremoved when the source code is compiled into bytecode. A placeholder isloaded, or inserted, into the bytecode in memory, in block 54. Forexample, in an embodiment, the placeholder includes the source code filelocation, along with the source code file line and column numbers thatdelineate the beginning and end of the segment of source codecorresponding to the code redacted from the bytecode memory.

In block 56, a request for debug information in the object is receivedfrom a runtime client, such as the error handling component or thereflection component of the virtual machine. The process checks, inblock 58, to verify whether or not the requested debug information iscurrently in memory. For example, if the debug information from theobject has previously been requested during program execution, and acleanup procedure, such as garbage collection, has not been performed inthe time that has intervened, then the requested debug information maystill be loaded in memory. If so, the requested debug information isread from memory and returned to the requesting client.

Otherwise, if the requested debug information is not currently inmemory, the corresponding source file location is retrieved, in block60. For example, in an embodiment, the on-demand debug informationloader reads the source file location in the placeholder in memory. Inblock 62, the object source code is re-parsed. For example, in anembodiment, the on-demand loader module asks the code loader module toreload the source code for the object, including the debug information.In block 64, the object source code is optionally recompiled, with theaccompanying debug information, into bytecode.

In some embodiments, the source code for the entire application, or partof the application source code in addition to that of the immediatefunction, such as the source code of a calling function or a calledfunction, is re-parsed and optionally recompiled in block 62 and block64. In particular, parsing and compiling the source code for the wholeapplication is required with programming languages that apply lexicalscoping, for example, dynamic scripting languages that use the “upvalue”concept. Otherwise, the resulting compiled function may not include thecorrect instructions and variables.

For example, in the Lua programming language, the following function canbe globally compiled or locally compiled with respect to function B( )with differing results:

function A( )    local a;    function B ( )       local b = a;      print (b);    end endFunction B( ) is correctly translated by globally compiling function A() before isolating function B( ) as follows:

.local “b” ; 0 .upvalue “a” ; 0 .const “print” 0 [1] getupval 0 0 ; a[2] getglobal 1 0 ; print [3] move 2 0 [ 4] call 1 2 1 [5] return 0 1However, locally compiling function B( ) yields an incorrect translationof function B( ) with different upvalue tables, as well as withdifferent instructions, as follows:

.local “b” ; 0 .const “a” ; 0 .const “print” ; 0 [1] getglobal 0 0 ; a[2] getglobal 1 1 ; print [3] move 2 0 [ 4] call 1 2 1 [5] return 0 1

In block 66, the debug information relevant to the request but notincluded in the bytecode in memory is identified, and in block 68, thedebug information is copied into the bytecode in memory.

Referring to FIG. 4, for example, the source code of a completeapplication written in a dynamic scripting language is compiled into atree structure 80, in accordance with block 62 and block 64 of FIG. 3. Afake top 82 represents the entry into the application, and the bytecodecorresponding to each of the functions in the application source code isrepresented in the tree: for example, Function A( ) 84, corresponding tosource code lines 1-10; Function D( ) 86, corresponding to source codelines 12-20; Function B( ) 88, corresponding to source code lines 3-5;and Function C( ) 90, corresponding to source code lines 7-9.

The tree structure 80 is searched by source location, and the debuginformation corresponding to the relevant function for which debuginformation was requested in accordance with block 56 of FIG. 3(depicted as Function B( ) in FIG. 4) is identified in accordance withblock 66 of FIG. 3. The debug information from the counterpart functionobject in the compiled tree is copied into the corresponding Function B() 92 in the bytecode in memory 94, supplementing or replacing theplaceholder that was included when the bytecode was initially compiled.

Referring again to FIG. 3, the requested debug information is returnedto the client, in block 70, in support of execution of the application.This completes the on-demand dynamic scripting-language source-codedebug information loading process.

Referring to FIG. 5, an exemplary process flow is illustrated that maybe performed, for example, by the dynamic-scripting-language virtualmachine 10 of FIG. 1 to implement another embodiment of the methoddescribed in this disclosure for on-demand dynamic scripting-languagesource-code loading. Blocks shown with dashed lines in FIG. 3 areoptional items that may not be performed in all implementations. Theprocess begins at block 100, where a function object, in the source codeof an application written in a dynamic-scripting-language is parsed. Forexample, in an embodiment, the function is parsed at run time by a codeloader module of a dynamic-scripting-language virtual machine.

The object is redacted, in block 102, to remove the function codesection. For example, in an embodiment, the function code is removedwhen the source code is compiled into bytecode. A placeholder is loaded,or inserted, into the bytecode in memory, in block 104. For example, inan embodiment, the placeholder includes the source code file location,along with the source code file line and column numbers that delineatethe beginning and end of the segment of source code corresponding to thecode redacted from the bytecode memory.

In block 106, a call or query request for the function is received froma runtime client, such as the execution component of the virtualmachine. The process checks, in block 108, to verify whether or not therequested function code section is currently in memory. For example, ifthe function has previously been requested during program execution, anda cleanup procedure, such as garbage collection, has not been performedin the time that has intervened, then the requested function code maystill be loaded in memory. If so, the requested function code is readfrom memory and returned to the requesting client, in block 120.

Otherwise, if the requested function code is not currently in memory,the corresponding source file location is retrieved, in block 110. Forexample, in an embodiment, the on-demand code section loader reads thesource file location in the placeholder in memory. In block 112, thefunction source code is re-parsed. For example, in an embodiment, theondemand loader module asks the code loader module to reload the sourcecode for the function object. In block 114, the object source code isoptionally recompiled into bytecode.

As explained above with reference to FIGS. 3 and 4, in some embodimentsthe source code for the entire application, or part of the applicationsource code in addition to that of the immediate function, such as thesource code of a calling function or a called function, is reparsed andoptionally recompiled in block 112 and block 114. In particular, parsingand compiling the source code for the whole application is required withprogramming languages that apply lexical scoping, for example, dynamicscripting languages that use the “upvalue” concept. Otherwise, theresulting compiled function may not include the correct instructions andvariables, as described above.

In block 116, the code that is relevant to the request but not includedin the bytecode in memory is identified, and in block 118, the completefunction is copied into the bytecode in memory. In an alternativeembodiment, the redacted code sections are stored in secondary storage,and the function can be copied directly from the secondary storage intothe bytecode in memory. The requested function is returned to theclient, in block 120, in support of execution of the application. Thiscompletes the on-demand dynamic-scripting-language source-code functionloading process.

In alternative embodiments, a cleanup process can be performed after therequested function or debug information has been returned. For example,a garbage collection process can remove the section code or debuginformation from the bytecode in memory to again reduce the memory spacerequired to store the bytecode.

Aspects of this disclosure are described herein with reference toflowchart illustrations or block diagrams, in which each block or anycombination of blocks can be implemented by computer programinstructions. The instructions may be provided to a processor of ageneral purpose computer, special purpose computer, or otherprogrammable data processing apparatus to effectuate a machine orarticle of manufacture, and when executed by the processor theinstructions create means for implementing the functions, acts or eventsspecified in each block or combination of blocks in the diagrams

In this regard, each block in the flowchart or block diagrams maycorrespond to a module, segment, or portion of code that including oneor more executable instructions for implementing the specified logicalfunction(s). It should also be noted that, in some alternativeimplementations, the functionality associated with any block may occurout of the order noted in the figures. For example, two blocks shown insuccession may, in fact, be executed substantially concurrently, orblocks may sometimes be executed in reverse order.

A person of ordinary skill in the art will appreciate that aspects ofthis disclosure may be embodied as a device, system, method or computerprogram product. Accordingly, aspects of this disclosure, generallyreferred to herein as circuits, modules, components or systems, may beembodied in hardware, in software (including firmware, residentsoftware, micro-code, etc.), or in any combination of software andhardware, including computer program products embodied in acomputer-readable medium having computer-readable program code embodiedthereon.

In this respect, any combination of one or more computer readable mediamay be utilized, including, but not limited to, an electronic, magnetic,optical, electromagnetic, infrared, or semiconductor system, apparatus,or device, or any suitable combination of these. More specific examplesof computer readable storage media would include the followingnonexhaustive list: a portable computer diskette, a hard disk, a randomaccess memory (RAM), a read-only memory (ROM), an erasable programmableread-only memory (EPROM), a Flash memory, a portable compact discread-only memory (CD-ROM), an optical storage device, network-attachedstorage (NAS), a storage area network (SAN), magnetic tape, or anysuitable combination of these. In the context of this disclosure, acomputer readable storage medium may include any tangible medium that iscapable of containing or storing program instructions for use by or inconnection with a data processing system, apparatus, or device.

Computer program code for carrying out operations regarding aspects ofthis disclosure may be written in any combination of one or moreprogramming languages, including object oriented programming languagessuch as Java, Smalltalk, C++, or the like, as well as conventionalprocedural programming languages, such as the “C,” FORTRAN, COBOL,Pascal, or the like. The program code may execute entirely on anindividual personal computer, as a stand-alone software package, partlyon a client computer and partly on a remote server computer, entirely ona remote server or computer, or on a cluster of distributed computernodes. In general, a remote computer, server or cluster of distributedcomputer nodes may be connected to an individual (user) computer throughany type of network, including a local area network (LAN), a wide areanetwork (WAN), an Internet access point, or any combination of these.

It will be understood that various modifications may be made. Forexample, useful results still could be achieved if steps of thedisclosed techniques were performed in a different order, and/or ifcomponents in the disclosed systems were combined in a different mannerand/or replaced or supplemented by other components. Accordingly, otherimplementations are within the scope of the following claims.

What is claimed is:
 1. A method implemented by one or more processors,wherein the one or more processors execute instructions stored on amemory to perform the method steps comprising: receiving a request for aredacted code section of compiled code; determining that the requestedredacted code section is not in a memory and based thereon: identifyinga location in a storage where the requested redacted code section isstored from a respective placeholder of the requested redacted codesection; obtaining the requested redacted code section from theidentified storage location; and modifying the compiled code to includethe obtained redacted code section.
 2. The method of claim 1 wherein theobtained redacted code section is a function definition or debugginginformation.
 3. The method of claim 2 wherein the obtained redacted codesection is a function definition and wherein modifying the compiled codeto include the obtained redacted code section comprises forming acomplete function in the compiled code using the obtained redacted codesection.
 4. The method of claim 1, wherein modifying the compiled codeto include the obtained redacted code section comprises: compiling theobtained redacted code section; and inserting the compiled redacted codesection into the compiled code in place of the placeholder.
 5. Themethod of claim 1 wherein identifying the location in the storagewherein the requested redacted code section is stored from therespective placeholder of the requested redacted code section comprises:obtaining a location of a file and an offset within the file where therequested redacted code section in stored.
 6. The method of claim 1wherein the request is a function call or a query of a functiondefinition.
 7. The method of claim 1, further comprising executing themodified compiled code.
 8. The method of claim 7 wherein the executionis within a virtual machine.
 9. The method of claim 1, furthercomprising, prior to receiving the request: redacting the code sectionfrom dynamic scripting language program source code.
 10. The method ofclaim 1, further comprising, prior to receiving the request: insertingthe respective placeholder in program source code for the redacted codesection to generate redacted program code.
 11. The method of claim 1,further comprising, prior to receiving the request: compiling redactedprogram code to generate the compiled code.
 12. A system comprising: amemory storage comprising instructions; and one or more processors incommunication with the memory, wherein the one or more processorsexecute the instructions to: receiving a request for a redacted codesection of compiled code; determine that the requested redacted codesection is not in a memory and based thereon: identify a location in astorage where the requested redacted code section is stored from arespective placeholder of the requested redacted code section; obtainthe requested redacted code section from the identified storagelocation; and modify the compiled code to include the obtained redactedcode section.
 13. The system of claim 12 wherein the obtained redactedcode section is a function definition or debugging information.
 14. Thesystem of claim 12 wherein the obtained redacted code section is afunction definition and wherein the one or more processors execute theinstructions to perform: form a complete function in the compiled codeusing the obtained redacted code section.
 15. The system of claim 12,wherein the one or more processors execute the instructions to perform:compile the obtained redacted code section; and insert the compiledredacted code section into the compiled code in place of theplaceholder.
 16. The system of claim 12, wherein the one or moreprocessors execute the instructions to perform: obtain a location of afile and an offset within the file where the requested redacted codesection in stored.
 17. The system of claim 12, wherein the request is afunction call or a query of a function definition.
 18. The system ofclaim 12, wherein the one or more processors execute the instructions toperform execute the modified compiled code.
 19. The system of claim 18wherein the execution is within a virtual machine.
 20. A non-transitorycomputer-readable medium storing instructions that, when executed by oneor more processors, cause the one or more processors execute theinstructions to: receive a request for a redacted code section ofcompiled code; determine that the requested redacted code section is notin a memory and based thereon: identify a location in a storage wherethe requested redacted code section is stored from a respectiveplaceholder of the requested redacted code section; obtain the requestedredacted code section from the identified storage location; and modifythe compiled code to include the obtained redacted code section.